/**
 * 
 */
package com.swfee.qinben.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.swfee.qinben.dao.DatabaseHelper;
import com.swfee.qinben.model.DbModel;

/**
 * @author ddr
 * 
 */
public abstract class DbBaseService<T extends DbModel> {
	protected DatabaseHelper dbHelper;
	protected SQLiteDatabase db;

	public DbBaseService(Context ctx) {
		dbHelper = new DatabaseHelper(ctx);
	}

	public List<T> getAll() {
		db = dbHelper.getWritableDatabase();
		Cursor cu = db.query(getTableName(), getClounms(), null, null, null,
				null, null);
		List<T> list = cursorToModels(cu);
		cu.close();
		db.close();
		return list;
	}

	public T findById(Serializable id) {
		db = dbHelper.getWritableDatabase();
		Cursor cu = db.query(getTableName(), getClounms(), getClounms()[0]
				+ "=?", new String[] { id + "" }, null, null, null);
		if (cu.moveToFirst()) {
			T t = cursorToModel(cu);
			cu.close();
			return t;
		}
		cu.close();
		db.close();

		return null;
	}

	public List<T> findByProps(Map<String, String> props) {
		return findByProps(props, null);
	}

	public List<T> findByProps(Map<String, String> props, String order) {
		db = dbHelper.getWritableDatabase();

		String wheres = " 1=1 ";
		String[] values = null;
		int i = 0;
		if (props != null && !props.isEmpty()) {
			values = new String[props.size()];
			for (String key : props.keySet()) {
				wheres += "and "+key + "=?";
				values[i++] = props.get(key);
			}
		} else {
			wheres = null;
			values = null;
		}
		Cursor cu = db.query(getTableName(), getClounms(), wheres, values,
				null, null, order);
		List<T> list = cursorToModels(cu);
		cu.close();
		db.close();

		return list;
	}

	public long insert(T t) {
		db = dbHelper.getWritableDatabase();
		long id = db.insert(getTableName(), null, t.toCloumnCotentValues());
		db.close();
		return id;
	};

	public long updateById(ContentValues contentValues, Serializable id) {
		db = dbHelper.getWritableDatabase();
		long i = db.update(getTableName(), contentValues, getClounms()[0]
				+ " = ?", new String[] { id + "" });

		db.close();
		return i;
	}

	public int deleteById(Serializable id) {
		db = dbHelper.getWritableDatabase();
		int i = db.delete(getTableName(), getClounms()[0] + " = ?",
				new String[] { id + "" });

		db.close();
		return i;
	}
	
	public int deleteAll() {
		db = dbHelper.getWritableDatabase();
		int i = db.delete(getTableName(), null,
				null);

		db.close();
		return i;
	}

	public abstract T cursorToModel(Cursor cu);

	private List<T> cursorToModels(Cursor cu) {
		List<T> list = new ArrayList<T>();
		while (cu.moveToNext()) {
			list.add(cursorToModel(cu));
		}
		return list;
	}

	public abstract String[] getClounms();

	public abstract String getTableName();

}
